﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Windows.Forms;
using oModbus;
using oModbus.Device;
using oModbus.Message;
using oModbus.Utility;

namespace Sample
{
    public partial class TestForm : Form
    {
        public TestForm()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            comboBoxSerialPorts.Items.Clear();
            foreach (var port in SerialPort.GetPortNames())
            {
                comboBoxSerialPorts.Items.Add(port);
            }
            if (comboBoxSerialPorts.Items.Count > 0)
                comboBoxSerialPorts.SelectedIndex = 0;
            comboBoxParity.Items.Clear();
            comboBoxParity.Items.Add(Parity.None.ToString());
            comboBoxParity.Items.Add(Parity.Odd.ToString());
            comboBoxParity.Items.Add(Parity.Even.ToString());
            comboBoxParity.Items.Add(Parity.Mark.ToString());
            comboBoxParity.Items.Add(Parity.Space.ToString());
            comboBoxParity.SelectedIndex = 0;
            comboBoxDataBits.SelectedIndex = 0;
            comboBoxStopBits.SelectedIndex = 0;
            BtnConnect.Enabled = true;
            BtnDisconnect.Enabled = false;
            comboBoxBaudRate.SelectedIndex = 1;

            fan_picture_Click(null, null);
            air_conditioner_picture_Click(null, null);
            ElectricBrake();
        }
        //  private ITransmission _transmission;
        private void BtnConnect_Click(object sender, EventArgs e)
        {
            SerialPort port = new SerialPort(comboBoxSerialPorts.Text)
            {
                BaudRate = Convert.ToInt32(comboBoxBaudRate.Text),
                DataBits = 8,
                // Parity = (Parity)(Convert.ToInt32(comboBoxParity.Text)),
                StopBits = StopBits.One
            };

            switch (comboBoxStopBits.Text)
            {
                case "None":
                    port.Parity = Parity.None;
                    break;
                case "Odd":
                    port.Parity = Parity.Odd;
                    break;
                case "Even":
                    port.Parity = Parity.Even;
                    break;
                case "Mark":
                    port.Parity = Parity.Mark;
                    break;
                case "Space":
                    port.Parity = Parity.Space;
                    break;
            }

            switch (comboBoxStopBits.Text)
            {
                case "None":
                    port.StopBits = StopBits.None;
                    break;
                case "1":
                    port.StopBits = StopBits.One;
                    break;
                case "1.5":
                    port.StopBits = StopBits.OnePointFive;
                    break;
                case "2":
                    port.StopBits = StopBits.Two;
                    break;

            }
            var temp = new SerialTransmission(port);
            if (temp.Open())
            {
                _slave = new ModbusSlave(1, temp);
                _slave.ReceivedMessageEvent += _transmission_ReceivedMessageEvent;
                _slave.SendMessageEvent += _slave_SendMessageEvent;
                // ReceivedMessageEvent+=   SendMessageEvent
                _slave.ReadCoilEvent += _slave_ReadCoilEvent;
                _slave.ReadDiscreteInputEvent += _slave_ReadDiscreteInputEvent;
                _slave.WriteSingleCoilEvent += _slave_WriteSingleCoilEvent;
                _slave.WriteSingleRegisterEvent += _slave_WriteSingleRegisterEvent;
                _slave.ReadHoldRegisterEvent += _slave_ReadHoldRegisterEvent;
                BtnConnect.Enabled = false;
                BtnDisconnect.Enabled = true;
            }
            else
            {
                MessageBox.Show(@"打开失败");
            }
        }

        private void _slave_WriteSingleRegisterEvent(WriteSingleRegisterRequest obj)
        {


            if (txtInfo.InvokeRequired)
            {
                //后端线程向主线程记日志
                Invoke(new Action<WriteSingleRegisterRequest>(_slave_WriteSingleRegisterEvent), obj);
            }
            else
            {
                switch (obj.RegisterAddress)
                {

                    case 0x0B:
                        SetTemperatureLbl.Text = @"设定温度：" + obj.Value;
                        _slave.Send(new WriteSingleCoilResponse(obj.MessageData.ToArray()));
                        break;

                }
                ////主线程直接记日志
                //if (ckbHex.Checked)
                //{
                //    txtInfo.Text += title + data.GetHexString() + Environment.NewLine;
                //}
                //else
                //{
                //    txtInfo.Text += title + data.GetHexString() + Environment.NewLine;
                //}
            }
        }

        private void _slave_SendMessageEvent(byte[] data)
        {
            Show("发送：", data);
        }

        private void _slave_ReadHoldRegisterEvent(ReadHoldRegisterRequest obj)
        {
            switch (obj.StartAddress)
            {
                case 0x00:
                    _slave.Send(new ReadHoldRegisterResponse(01, ((ushort)0xff).GetBytes().ToList()));
                    break;
                case 0x09:
                    _slave.Send(new ReadHoldRegisterResponse(01, _airSupply.GetBytes().ToList()));
                    break;
                case 0xa:
                    _slave.Send(new ReadHoldRegisterResponse(01, _airReturn.GetBytes().ToList()));
                    break;
                case 0x13:
                    _slave.Send(new ReadHoldRegisterResponse(01, _electricBrake.GetBytes().ToList()));
                    break;

                case 0x14:
                    _slave.Send(new ReadHoldRegisterResponse(01, _voltag.GetBytes().ToList()));
                    break;
                case 0x15:
                    _slave.Send(new ReadHoldRegisterResponse(01, _galvanic.GetBytes().ToList()));
                    break;
                case 0x1d:
                    _slave.Send(new ReadHoldRegisterResponse(01, _pressure.GetBytes().ToList()));
                    break;
                case 0x1E:
                    _slave.Send(new ReadHoldRegisterResponse(01, _waterLevel.GetBytes().ToList()));
                    break;

            }
        }

        private void _slave_ReadCoilEvent(ReadCoilRequest obj)
        {
            ReadCoilResponse response = new ReadCoilResponse(_slave.SlaveId, new byte[] { 0x01, 02 }.ToList());
            _slave.Send(response);
        }

        private ModbusSlave _slave;
        private void _transmission_ReceivedMessageEvent(byte[] data)
        {
            Show("接受：", data);
        }

        private void Show(string title, byte[] data)
        {
            if (txtInfo.InvokeRequired)
            {
                //后端线程向主线程记日志
                Invoke(new Action<string, byte[]>(Show), title, data);
            }
            else
            {
                //主线程直接记日志
                if (ckbHex.Checked)
                {
                    txtInfo.Text += title + data.GetHexString() + Environment.NewLine;
                }
                else
                {
                    txtInfo.Text += title + data.GetHexString() + Environment.NewLine;
                }
            }
        }

        private void BtnDisconnect_Click(object sender, EventArgs e)
        {
            //_transmission.Close();
            //_transmission.ReceivedMessageEvent -= _transmission_ReceivedMessageEvent;

            _slave.Close();
            _slave.ReceivedMessageEvent -= _transmission_ReceivedMessageEvent;

            BtnConnect.Enabled = true;
            BtnDisconnect.Enabled = false;
        }



        private void btnClear_Click(object sender, EventArgs e)
        {
            txtInfo.Text = "";
        }

        #region 风扇

        private void _slave_ReadDiscreteInputEvent(ReadDiscreteInputRequest obj)
        {

            List<byte> temp;
            switch (obj.StartAddress)
            {
                case 0x00:
                    temp = _fanNormal ? new List<byte> { 0xff } : new List<byte> { 0 };
                    _slave.Send(new ReadDiscreteInputResponse(1, temp));
                    break;
                case 0x01:
                    temp = _fanFail ? new List<byte> { 0xff } : new List<byte> { 0 };
                    _slave.Send(new ReadDiscreteInputResponse(1, temp));
                    break;
                case 0x02:
                    temp = _fanFault ? new List<byte> { 0xff } : new List<byte> { 0 };
                    _slave.Send(new ReadDiscreteInputResponse(1, temp));
                    break;
            }

        }

        private void _slave_WriteSingleCoilEvent(WriteSingleCoilRequest obj)
        {

            switch (obj.CoilAddress)
            {
                case 0:
                    if (obj.Value == 0)
                    {
                        fan_picture.Image = Image.FromFile("fan.png");
                        _fan = true;
                    }
                    else
                    {
                        fan_picture.Image = Image.FromFile("fan.gif");
                        _fan = false;

                    }
                    _slave.Send(new WriteSingleCoilResponse(obj.MessageData.ToArray()));
                    break;
                case 0x09:
                    if (obj.Value == 0)
                    {
                        air_conditioner_picture.Image = Image.FromFile("airconditioner.png");
                        _air = true;
                    }
                    else
                    {
                        air_conditioner_picture.Image = Image.FromFile("airconditioner.gif");
                        _air = false;

                    }
                    _slave.Send(new WriteSingleCoilResponse(obj.MessageData.ToArray()));
                    break;
            }


        }

        private bool _fanNormal;
        //风扇
        private void fan_normal_btn_Click(object sender, EventArgs e)
        {
            // _slave.Send(new ReadDiscreteInputResponse(1, new List<byte> { 0xff }));
            if (IsCon())
            {
                if (_fanNormal)
                {
                    fan_normal_btn.BackColor = Color.Gainsboro;
                    _fanNormal = false;
                }
                else
                {
                    fan_normal_btn.BackColor = Color.Chartreuse;

                    _fanNormal = true;
                }
            }
        }

        private bool _fanFail;
        private void fan_fail_btn1_Click(object sender, EventArgs e)
        {
            //if (IsCon())
            //    _slave.Send(new ReadDiscreteInputResponse(1, new List<byte> { 0 }));

            if (IsCon())
            {

                if (_fanFail)
                {
                    fan_fail_btn1.BackColor = Color.Gainsboro;
                    _fanFail = false;
                }
                else
                {
                    fan_fail_btn1.BackColor = Color.Chartreuse;
                    _fanFail = true;
                }
            }
        }

        private bool _fanFault;
        private void fan_fault_btn_Click(object sender, EventArgs e)
        {
            if (IsCon())
            {

                if (_fanFault)
                {
                    fan_fault_btn.BackColor = Color.Gainsboro;
                    _fanFault = false;
                }
                else
                {
                    fan_fault_btn.BackColor = Color.Chartreuse;
                    _fanFault = true;
                }
            }

        }

        private bool _fan;
        private void fan_picture_Click(object sender, EventArgs e)
        {
            if (_fan)
            {
                fan_picture.Image = Image.FromFile("fan.gif");
                _fan = false;
            }
            else
            {
                fan_picture.Image = Image.FromFile("fan.png");
                _fan = true;
            }

        }

        #endregion

        #region 空调

        bool IsCon()
        {
            if (_slave == null)
            {
                MessageBox.Show(@"请先连接通讯端口");
                return false;
            }

            return true;
        }

        private ushort _airSupply;
        /// <summary>
        /// 空调
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void air_supply_btn_Click(object sender, EventArgs e)
        {

            if (IsCon())
            {
                DialogBox box = new DialogBox("设置 送风温度", "温度")
                {
                    Execute = num =>
                    {
                        {
                            _airSupply = num;
                            air_supply_lbl.Text = @"送风温度:" + _airSupply;
                            //byte[] inputState = num.GetBytes();
                            ////  _slave.Send(new ReadInputRegisterResponse(1, inputState.ToList()));
                            //var temp = new ReadHoldRegisterResponse(1, inputState.ToList()).PackingMessage();
                            //Show(temp);
                            //_slave.Send(new ReadHoldRegisterResponse(1, inputState.ToList()));
                            //MessageBox.Show(x);
                        }
                    }
                };

                box.Show();

            }

        }

        private ushort _airReturn;
        private void air_return_btn_Click(object sender, EventArgs e)
        {
            if (IsCon())
            {
                DialogBox box = new DialogBox("设置 送风温度", "温度")
                {
                    Execute = num =>
                    {
                        {
                            _airReturn = num;
                            air_return_lbl.Text = @"送风温度:" + _airReturn;
                            //byte[] inputState = { 0xff }; 
                            //num.GetBytes(); 
                            //var temp = new ReadDiscreteInputResponse(1, inputState.ToList()).PackingMessage();
                            //Show(temp);
                            //_slave.Send(new ReadDiscreteInputResponse(1, inputState.ToList()));

                        }
                    }
                };

                box.Show();

            }
        }

        private bool _air;
        private void air_conditioner_picture_Click(object sender, EventArgs e)
        {
            if (_air)
            {
                air_conditioner_picture.Image = Image.FromFile("airconditioner.gif");
                _air = false;
            }
            else
            {
                air_conditioner_picture.Image = Image.FromFile("airconditioner.png");
                _air = true;
            }
        }
        #endregion

        #region 电站


        private ushort _electricBrake = 2;




        private void ElectricBrake()
        {
            switch (_electricBrake)
            {
                case 1:
                    Closing_btn.BackColor = Color.Chartreuse;
                    sluice_btn.BackColor = Color.Gainsboro;
                    alarm_btn.BackColor = Color.Gainsboro;
                    break;
                case 2:
                    Closing_btn.BackColor = Color.Gainsboro;
                    sluice_btn.BackColor = Color.Chartreuse;
                    alarm_btn.BackColor = Color.Gainsboro;
                    break;
                case 3:
                    Closing_btn.BackColor = Color.Gainsboro;
                    sluice_btn.BackColor = Color.Gainsboro;
                    alarm_btn.BackColor = Color.Chartreuse;
                    break;

            }

        }
        /// <summary>
        ///  电流
        /// </summary>
        private ushort _galvanic;
        /// <summary>
        /// 电压
        /// </summary>
        private ushort _voltag;
        /// <summary>
        /// 合闸
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Closing_btn_Click(object sender, EventArgs e)
        {
            if (IsCon())
            {
                _galvanic = 10;
                _voltag = 220;
                _electricBrake = 1;
                voltag_lbl.Text = @"电压:" + _voltag;
                galvanic_lbl.Text = @"电流:" + _voltag;
                ElectricBrake();
            }
        }
        /// <summary>
        /// 分闸
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sluice_btn_Click(object sender, EventArgs e)
        {
            if (IsCon())
            {
                _galvanic = 0;
                _voltag = 0;
                voltag_lbl.Text = @"电压:" + _voltag;
                galvanic_lbl.Text = @"电流:" + _voltag;
                _electricBrake = 2;
                ElectricBrake();
            }
        }
        /// <summary>
        /// 报警
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void alarm_btn_Click(object sender, EventArgs e)
        {
            if (IsCon())
            {
                _electricBrake = 3;
                ElectricBrake();
            }
        }

        /// <summary>
        /// 电压
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void voltage_btn_Click(object sender, EventArgs e)
        {
            if (IsCon())
            {
                DialogBox box = new DialogBox("设置 电压", "电压")
                {
                    Execute = num =>
                    {
                        {
                            _voltag = num;
                            voltag_lbl.Text = @"电压:" + _voltag;
                        }
                    }
                };

                box.Show();

            }
        }
        /// <summary>
        /// 电流
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void galvanic_btn_Click(object sender, EventArgs e)
        {
            if (IsCon())
            {
                DialogBox box = new DialogBox("设置 电流", "电流")
                {
                    Execute = num =>
                    {
                        {
                            _galvanic = num;
                            galvanic_lbl.Text = @"电流:" + _galvanic;
                        }
                    }
                };

                box.Show();

            }
        }

        #endregion

        #region 公共区域

        private ushort _pressure = 0;

        private ushort _waterLevel = 0;
        /// <summary>
        /// 水位
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void water_level_btn_Click(object sender, EventArgs e)
        {
            if (IsCon())
            {
                DialogBox box = new DialogBox("设置 水位", "水位")
                {
                    Execute = num =>
                    {
                        {
                            _waterLevel = num;
                            water_level_lbl.Text = @"水位:" + _waterLevel;
                        }
                    }
                };

                box.Show();

            }
        }
        /// <summary>
        /// 水压
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void pressure_btn_Click(object sender, EventArgs e)
        {
            if (IsCon())
            {
                DialogBox box = new DialogBox("设置 水压", "水压")
                {
                    Execute = num =>
                    {
                        {
                            _pressure = num;
                            pressure_lbl.Text = @"水压:" + _pressure;
                        }
                    }
                };

                box.Show();

            }
        }
        #endregion



    }
}
